package com.rlz.base.base;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import com.google.gson.JsonSyntaxException;
import com.trello.rxlifecycle2.components.support.RxFragment;
import com.rlz.base.R;
import com.rlz.base.util.Paging;
import com.rlz.base.util.ToastUtils;
import com.rlz.base.weiget.StateView;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.ViewModelProvider;

/**
 * Created by RLZ
 * on 2021/4/8
 */
public abstract class BaseFragment<M extends BaseModel, VM extends BaseViewModel<M>, DB extends ViewDataBinding>
        extends RxFragment {

    protected View mContentView;
    protected VM mViewModel;
    protected DB mBinding;
    protected Bundle mBundle;
    protected Paging mPaging;


    /**
     * 创建布局文件
     */
    protected abstract int createLayoutId();

    /**
     * 处理业务逻辑
     */
    protected abstract void processLogic();

    /**
     * 处理点击事件
     */
    protected void onClicks() {
        mBundle = new Bundle();
    }

    @Nullable
    @Override
    public View onCreateView(@NotNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        if (mContentView == null) {
            mBinding = DataBindingUtil.inflate(inflater, createLayoutId(), container, false);
            mContentView = mBinding.getRoot();
            mBinding.setLifecycleOwner(this);
            createViewModel();
            processLogic();
        } else {
            ViewGroup parent = (ViewGroup) mContentView.getParent();
            if (parent != null) {
                parent.removeView(mContentView);
            }
        }
        return mContentView;
    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        onClicks();
    }

    private void createViewModel() {
        if (mViewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = EmptyViewModel.class;
            }
            mViewModel = (VM) new ViewModelProvider(this).get(modelClass);
            mViewModel.setObjectLifecycleTransformer(bindToLifecycle());
        }
    }

    protected void Toast(@NonNull String msg) {
        ToastUtils.showToast(msg);
    }

    public void toActivity(Class<?> clazz) {
        toActivity(clazz, mBundle);
    }

    public void toActivity(Class<?> clazz, Bundle bundle) {
        Intent intent = new Intent(getActivity(), clazz);
        if (bundle != null && !bundle.isEmpty()) intent.putExtras(bundle);
        startActivity(intent);
        mBundle.clear();
    }

    public abstract class OnCallback<T> implements Resource.OnHandleCallback<T> {
        @Override
        public void onLoading(String msg) {
            show(msg);
        }

        @Override
        public void onError(Throwable throwable) {
            dismiss();
            if (throwable instanceof ConnectException) {
                Toast(getResources().getString(R.string.result_server_error));
                if (mPaging != null)
                    showStateView(StateView.NO_NETWORK);
            } else if (throwable instanceof SocketTimeoutException)
                Toast(getResources().getString(R.string.result_server_timeout));
            else if (throwable instanceof JsonSyntaxException)
                Toast(getString(R.string.result_resolve_error));
            else Toast(getResources().getString(R.string.result_empty_error));

            if (mPaging != null)
                showStateView(StateView.ERROR);
        }

        @Override
        public void onCompleted() {
            dismiss();
        }

        @Override
        public void onFailure(String msg) {
            Toast(msg);
        }
    }

    protected void show(String msg) {
        if (getActivity() != null && !getActivity().isFinishing())
            if (mPaging != null) {
                if (mPaging.curPage == 0) {
                    ((BaseActivity) getActivity()).show(msg);
                }
            } else ((BaseActivity) getActivity()).show(msg);
    }

    protected void dismiss() {
        if (getActivity() != null && !getActivity().isFinishing())
            ((BaseActivity) getActivity()).dismiss();
    }

    protected void showStateView(@StateView.Flavour int status) {
        showStateView(status, "");
    }

    protected void showStateView(@StateView.Flavour int status, String msg) {
        StateView stateView = getView().findViewById(R.id.state_view);
        if (stateView == null) return;
        if (TextUtils.isEmpty(msg))
            stateView.setStatus(status);
        else
            stateView.setStatus(status, msg);
        stateView.setOnReloadListener(this::retryClick);
    }

    protected void retryClick(View view) {

    }
}
